package dk.flashnotes.fff.googleAnalytics {
	import flash.display.DisplayObjectContainer;	
	import flash.display.DisplayObject;	
	import flash.events.IOErrorEvent;	
	
	import com.google.analytics.v4.GoogleAnalyticsAPI;	
	
	import org.osflash.thunderbolt.Logger;
	
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;		

	/**
	 * @author jk
	 */
	public class GABridge extends EventDispatcher {

		private var _sModulePath : String;
		private var _oExternalConfigLoader : URLLoader;
		private var _doModuleLoader : Loader;
		private static var MODULE_FILENAME : String="fff_ga_module.swf";
		private static var sEXTERNAL_CONFIG_XML_FILENAME : String = "base_config.xml";
		private var _oGABaseConfig : GABaseConfig;
		private var _oGAWrapper : IGAWrapper;
		private var _oLoadContext : LoaderContext;
		private var _oGAApi : GoogleAnalyticsAPI;
		private var _sConfigID : String;
		private var _doDisplayObject : DisplayObjectContainer;

		//private var _oGAApi : GoogleAnalyticsAPI;

		public function GABridge() {
			super();
			setup();
		}
		
		private function setup() : void {
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// public api
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		
		/**
		 * Load and initialize the Google Analytics API
		 * This will load the external swf making the GA API avalible. 
		 * 
		 * @param sModulePath				The path for the external files: 'base_config.xml' and 'fff_ga_module.swf'.
		 * @param sConfigID					The config id is used to refrence different config modes in the 'base_config.xml'.
		 * @param doDisplayObjectContainer	The DisplayObjectContainer is used to refrence the stage. Used by the GA debug tool.
		 */
		public function loadAndInitialize(sModulePath:String, sConfigID : String, doDisplayObjectContainer : DisplayObjectContainer) : void {
			_doDisplayObject = doDisplayObjectContainer;
			_sConfigID = sConfigID;
			_sModulePath = sModulePath;
			
			if(_sModulePath.substr((_sModulePath.length-1), 1)!="/") {
				_sModulePath+='/';
			}
			loadExternalConfig();
		}
		
		/**
		 * Passes the PageView specified on to the GATracker.
		 * 
		 * @param sURL			The url to track in GA.
		 */
		public function trackPageview(sURL : String) : void {
			// the use of # has been disabled as it does not looks like it is working 
			//var sPageTrackString : String=_oGABaseConfig.sPageUrlPreString+'#'+sURL;
			
			_oGAApi.trackPageview(sURL);
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// load moudle
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function loadModule() : void {
			
			_doModuleLoader = new Loader();
			_doModuleLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onModuleLoadComplete, false, 0, true);
			
			_oLoadContext = new LoaderContext();
			_oLoadContext.applicationDomain = ApplicationDomain.currentDomain;	
			
			_doModuleLoader.load(new URLRequest(_sModulePath + GABridge.MODULE_FILENAME));
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// setup tracker
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function onModuleLoadComplete(event : Event) : void {
			_oGAWrapper=_doModuleLoader.content as IGAWrapper;
			
			_oGAApi=_oGAWrapper.get_oGAApi(_oGABaseConfig);
			
			// looks like this is not working.
			_oGAApi.setAllowAnchor(true);
			
			dispatchEvent(new GABridgeEvent(GABridgeEvent.LOADED_AND_READY));
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// load external config file
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function loadExternalConfig() : void {
			_oExternalConfigLoader = new URLLoader();
			_oExternalConfigLoader.addEventListener(Event.COMPLETE, onExternalConfigLoaded, false, 0, true);
			_oExternalConfigLoader.load(new URLRequest(_sModulePath + GABridge.sEXTERNAL_CONFIG_XML_FILENAME));
			_oExternalConfigLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorLoadingExtConfig, false, 0, true);
		}
		
		private function onIOErrorLoadingExtConfig(event : IOErrorEvent) : void {
			throw new Error("External config file for GA not found on path: " + _sModulePath + GABridge.sEXTERNAL_CONFIG_XML_FILENAME);
		}

		private function onExternalConfigLoaded(event : Event) : void {
			var xmlConfig:XML=get_xmlConfigFromConfigID(_sConfigID);
			_oGABaseConfig = new GABaseConfig(xmlConfig, _doDisplayObject);
			loadModule();
		}

		private function get_xmlConfigFromConfigID(sConfigID : String) : XML {
			for each (var xmlConfigItems : XML in XML(XML(_oExternalConfigLoader.data)).config_item) {
				if(xmlConfigItems.@id == sConfigID) {
					return xmlConfigItems;
				}
			}
			throw new Error("Missing GA 'config_item' with id: " + _sConfigID);
			return null;
		}
	}
}
